<script setup lang="ts">
import {
  defineModel,
  ref,
  watch,
  shallowRef,
  useTemplateRef,
  nextTick
} from "vue";
import { ElLoading, ElMessage } from "element-plus";
import { UploadFilled } from "@element-plus/icons-vue";
import excelJs from "exceljs";
import { saveAs } from "file-saver";
import { isMobile } from "@/utils/utils";

const emits = defineEmits(["submit"]);
const dialogVisible = defineModel();
const fileMaxSize = ref(10); // mb
const fileList = shallowRef([]);

// excel 模板
const downloadExcelTemplate = async function () {
  // 创建一个新的工作簿
  const workbook = new excelJs.Workbook();

  // 添加一个工作表，可以指定名称
  const worksheet = workbook.addWorksheet("班级数据");

  worksheet.columns = [
    { header: "学生名称（必填）", key: "stu_name", width: 20 },
    { header: "学号", key: "stu_number", width: 20 },
    { header: "年级", key: "grade", width: 20 },
    { header: "电话", key: "phone", width: 20 },
    { header: "邮箱", key: "email", width: 20 },
    { header: "住址", key: "address", width: 20 }
  ];

  // 获取表头行
  const headerRow = worksheet.getRow(1);

  // 设置表头样式
  headerRow.eachCell(cell => {
    cell.font = {
      name: "微软雅黑",
      size: 10,
      bold: true,
      color: { argb: "FFFFFFFF" }
    };
    cell.fill = {
      type: "pattern",
      pattern: "solid",
      fgColor: { argb: "FF0070C0" }
    };
    cell.alignment = { vertical: "middle", horizontal: "center" };
  });

  try {
    // 将工作簿转换为 Buffer
    const buffer = await workbook.xlsx.writeBuffer();

    // 创建 Blob 对象并下载
    const blob = new Blob([buffer], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    });
    saveAs(blob, "班级数据模板.xlsx");
  } catch (error) {
    console.error("导出 excel 失败:", error);
  }
};

const onFileChange = function (file) {
  const isLarge = file.size > fileMaxSize.value * 1024 * 1024;
  if (!isLarge) {
    fileList.value.push(file);
  }
};

// 解析 excel
const parseExcel = async function (file) {
  const workbook = new excelJs.Workbook();
  await workbook.xlsx.load(file.arrayBuffer());

  const worksheet = workbook.getWorksheet(1);
  const students = [];
  worksheet.eachRow(function (row, rowNumber) {
    if (rowNumber === 1) return;

    const stuObj = {
      stu_name: row.getCell(1).value,
      stu_number: row.getCell(2).value,
      grade: row.getCell(3).value,
      phone: row.getCell(4).value,
      email: row.getCell(5).value,
      address: row.getCell(6).value
    };

    if (stuObj.stu_name) {
      stuObj.stu_name = String(stuObj.stu_name).trim();
      students.push(stuObj);
    }
  });
  return students;
};

const submitHandle = async function () {
  if (!fileList.value.length) {
    return ElMessage({
      message: "请选上传 excel 文件",
      type: "warning",
      grouping: true
    });
  }

  const loading = ElLoading.service({
    lock: true,
    text: "excel 解析中...",
    background: "rgba(0, 0, 0, 0.2)"
  });
  const allExcelData = [];
  for (const file of fileList.value) {
    try {
      const students = await parseExcel(file.raw);
      allExcelData.push({
        class_name: file.name.split(".")[0],
        stu_list: students
      });
    } catch (error) {
      console.log(error);
    }
  }
  loading.close();
  emits("submit", allExcelData);
};

const uploadRef = useTemplateRef("uploadRef");

watch(dialogVisible, visible => {
  if (!visible) {
    fileList.value.length = 0;
    uploadRef?.value?.clearFiles();
  }
});
</script>

<template>
  <ElDialog
    v-model="dialogVisible"
    title="Excel 导入"
    width="520"
    :close-on-click-modal="false"
    :fullscreen="isMobile()"
  >
    <ElButton class="download-btn" type="primary" @click="downloadExcelTemplate"
      >下载 excel 模板</ElButton
    >
    <ElUpload
      ref="uploadRef"
      v-model:file-list="fileList"
      :on-change="onFileChange"
      :auto-upload="false"
      accept=".xls,.xlsx"
      class="upload"
      drag
      multiple
    >
      <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
      <div class="el-upload__text">拖拽文件到此或 <em>点击上传</em></div>
      <template #tip>
        <div class="el-upload__tip">
          可同时上传多个 excel 文件，大于 {{ fileMaxSize }} MB
          的文件会被过滤，文件名将作为班级名称，示例：三年级一班.xls、四年级二班.xlsx。
        </div>
      </template>
    </ElUpload>
    <template #footer>
      <div class="dialog-footer">
        <ElButton @click="dialogVisible = false">取消</ElButton>
        <ElButton type="primary" @click="submitHandle"> 确定 </ElButton>
      </div>
    </template>
  </ElDialog>
</template>

<style scoped lang="scss">
.download-btn {
  margin-bottom: 10px;
}
.file-name-tips {
  font-weight: 700;
}
.el-upload__tip {
  color: #67c23a;
}
.upload {
  :deep(.el-icon--close) {
    display: inline-flex !important;
  }
}
</style>
